package sfeir.ergosum;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import sfeir.ergosum.dao.DatabaseConnection;
import sfeir.ergosum.dao.DatabaseProvider;
import sfeir.ergosum.model.Contact;
import sfeir.ergosum.model.Group;
import sfeir.ergosum.tools.AnimationTools;
import sfeir.ergosum.tools.CachedImageView;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;

public class ContactManagerActivity extends ListActivity {
    private static DatabaseProvider DP;
    private HashMap<Integer, Long> hmPosIdContact;
    private static Thread mThread = null;
    private Handler mHandler = new Handler();
    private ProgressDialog mProgressDialog;

    final Runnable refresh = new Runnable() {
        public void run() {
            //            ContactManagerActivity.this.onCreate(null);
            ContactManagerActivity.this.setResult(RESULT_OK);
            ContactManagerActivity.this.finish();
        }
    };

    public final static int MENU_SELECT_ALL = 0x01;
    public final static int MENU_DESELECT_ALL = 0x02;
    public final static int MENU_MOVE = 0x03;
    public final static int MENU_ERASE = 0x04;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list);

        DP = new DatabaseProvider(new DatabaseConnection(this));
        long groupId = getIntent().getLongExtra("groupId", -11);

        List<Contact> allContacts;
        DP.open();
        if(groupId == -11) {
            allContacts = DP.getAllLightContacts(false,false);
            setTitle(R.string.all_contacts);
        } else {
            allContacts = DP.getAllLightContactsFromGroup(groupId);
            setTitle(getIntent().getStringExtra("groupName"));
            getIntent().removeExtra("groupId");
            getIntent().removeExtra("groupName");
        }
        DP.close();

        if(!allContacts.isEmpty()) {
            hmPosIdContact = new HashMap<Integer, Long>();
            List<String> mString = new ArrayList<String>();
            int i = 0;
            for(Contact c: allContacts) {
                mString.add(c.getAlias());
                hmPosIdContact.put(i++, c.getId());
            }

            setListAdapter(new ArrayAdapter<String>(this,
                    android.R.layout.simple_list_item_multiple_choice, mString));

            final ListView listView = getListView();

            listView.setItemsCanFocus(false);
            listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
            AnimationTools.setAnimation(listView);
        } else {
            ((TextView)findViewById(android.R.id.empty)).setText(R.string.no_contacts);
            setListAdapter(null);

        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, MENU_SELECT_ALL, 0, R.string.select_all).setIcon(R.drawable.button_ok);
        menu.add(0, MENU_DESELECT_ALL, 0, R.string.deselect_all).setIcon(R.drawable.button_cancel);
        menu.add(0, MENU_MOVE, 0, R.string.main_context_menu_moveto).setIcon(R.drawable.fileimport);
        menu.add(0, MENU_ERASE, 0, R.string.main_context_menu_delete).setIcon(R.drawable.remove_group);

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        final int count = getListAdapter().getCount();
        switch (item.getItemId()) {
        case MENU_SELECT_ALL:
            setAllItemsChecked(true);
            //            getListView().setEnabled(true);
            break;
        case MENU_DESELECT_ALL:
            setAllItemsChecked(false);
            break;
        case MENU_MOVE:
            getSpinnerDialog(count).show();
            break;
        case MENU_ERASE:
            AlertDialog dialog =  new AlertDialog.Builder(this)
            .setTitle(R.string.delete_contact_confirmation)
            .setIcon(R.drawable.alert_dialog_icon)
            .setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    /* User clicked OK so do some stuff */
                    erase(count);
                }
            }).setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    /* User clicked cancel so do some stuff */
                }
            }).create();
            dialog.show();
            break;
        default:
            break;
        }
        return super.onMenuItemSelected(featureId, item);
    }

    private void setAllItemsChecked(boolean bool) {
        ListView listView = getListView();
        for (int i=0; i<getListAdapter().getCount(); i++) {
            listView.setItemChecked(i, bool);
        }
    }

    private void erase(final int count) {
        mProgressDialog = getProgressDialog(getString(R.string.delete_contact_wait), count);
        mThread = new Thread() {
            public void run() {
                ListView listView = getListView();
                DP.open();
                Contact contact;
                for (int i=0; i<count; i++) {
                    if(listView.getCheckedItemPositions().get(i)) {
                        contact = DP.getFullContact(hmPosIdContact.get(i));
                        DP.removeContact(contact);
                        deletePhotoInCache(ContactManagerActivity.this, contact);
                    }
                    mProgressDialog.setProgress(i);
                }
                DP.close();
                mProgressDialog.dismiss();
                mHandler.post(refresh);
            }
        };
        mProgressDialog.show();
        mThread.start();
    }

    private void moveContacts(final int count, final long groupId) {
        mProgressDialog = getProgressDialog(getString(R.string.delete_contact_wait), count);
        mThread = new Thread() {
            public void run() {
                ListView listView = getListView();
                DP.open();
                for (int i=0; i<count; i++) {
                    if(listView.getCheckedItemPositions().get(i)) {
                        Contact contact = (Contact) DP.getLightContact(hmPosIdContact.get(i));
                        contact.setGroupId(groupId);

                        DP.updateContactOnly(contact);
                    }
                    mProgressDialog.setProgress(i);
                }
                DP.close();
                mProgressDialog.dismiss();
                mHandler.post(refresh);
            }
        };
        mProgressDialog.show();
        mThread.start();
    }

    public static void deletePhotoInCache(Context context, Contact contact) {
        if (contact.getPerson().getPhoto().getImageUrl() != null) {
            context.deleteFile(
                    CachedImageView.md5(
                            contact.getPerson().getPhoto().getImageUrl()));
        }
    }

    private ProgressDialog getProgressDialog(String title, int max) {
        ProgressDialog mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setTitle(title);
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setIcon(R.drawable.icon);
        mProgressDialog.setMax(max);
        mProgressDialog.setButton2(this.getText(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                mThread.stop();
                dialog.dismiss();
            }
        });
        return mProgressDialog;
    }

    private Dialog getSpinnerDialog(final int nbContactsSelected) {
        LayoutInflater factory = LayoutInflater.from(this);
        final View entryView = factory.inflate(R.layout.spinner_dialog,
                null);
        final TextView textInstruction = 
            (TextView) entryView.findViewById(R.id.instruction_dialog);
        final Spinner spinner = 
            (Spinner) entryView.findViewById(R.id.spinner);

        textInstruction.setText(R.string.moveto_instruction);
        spinner.setPromptId(R.string.moveto_prompt);

        DP.open();
        ArrayAdapter<Group> adapter = 
            new ArrayAdapter<Group>(this,
                    android.R.layout.simple_spinner_item,
                    DP.getAllGroups());
        DP.close();
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);

        return new AlertDialog.Builder(this)
        .setTitle(R.string.moveto).setView(entryView)
        .setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                /* User clicked OK so do some stuff */
                moveContacts(nbContactsSelected, ((Group) spinner.getSelectedItem()).getId());
            }
        }).setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,
                    int whichButton) {
                /* User clicked cancel so do some stuff */
            }
        }).create();
    }

    public static void updateContact(Context context, Contact contact) {
        DP = new DatabaseProvider(new DatabaseConnection(context));
        DP.open();
        DP.updateContactOnly(contact);
        DP.close();
    }

    public static void deleteContact(Context context, Contact contact) {
        DP = new DatabaseProvider(new DatabaseConnection(context));
        DP.open();
        DP.removeContact(contact);
        DP.close();
    }

    public static List<Group> getAllGroup(Context context) {
        DP = new DatabaseProvider(new DatabaseConnection(context));
        DP.open();
        List<Group> groups = DP.getAllGroups();
        DP.close();
        return groups;
    }

    public static void updateGroup(Context context, Group group) {
        DP = new DatabaseProvider(new DatabaseConnection(context));
        DP.open();
        DP.updateGroup(group);
        DP.close();
    }

    public static void deleteGroup(Context context, Group group) {
        DP = new DatabaseProvider(new DatabaseConnection(context));
        DP.open();
        DP.removeGroup(group.getId());
        DP.close();
    }

    public static void addGroup(Context context, String nameGroup) {
        DP = new DatabaseProvider(new DatabaseConnection(context));
        DP.open();
        DP.insertGroup(new Group(0, nameGroup));
        DP.close();
    }
}
